package mqtt

import (
	"encoding/json"
	"fmt"
	"log"
	"os"

	mqtt "github.com/eclipse/paho.mqtt.golang"
	"github.com/go-basic/uuid"
	"github.com/spf13/viper"
)

var mqtt_client mqtt.Client

func Init() {
	listenMQTT()
}

func listenMQTT() {
	broker := os.Getenv("MQTT_HOST")
	if broker == "" {
		broker = viper.GetString("mqtt.broker")
	}
	clientid := uuid.New()
	fmt.Println("mqtt clientid", clientid)
	username := viper.GetString("mqtt.username")
	password := viper.GetString("mqtt.password")

	var connectLostHandler mqtt.ConnectionLostHandler = func(client mqtt.Client, err error) {
		fmt.Printf("Connect lost: %v", err)
	}
	opts := mqtt.NewClientOptions()
	opts.SetUsername(username)
	opts.SetPassword(password)
	opts.SetClientID(clientid)
	opts.AddBroker(broker)
	opts.SetAutoReconnect(true) //自动重连
	opts.SetOrderMatters(false)
	opts.OnConnectionLost = connectLostHandler
	opts.SetOnConnectHandler(func(c mqtt.Client) {
		log.Println("MQTT客户端连接成功...", broker)
	})
	mqtt_client = mqtt.NewClient(opts)
	if token := mqtt_client.Connect(); token.Wait() && token.Error() != nil {
		log.Println("mqtt客户端连接异常...", viper.GetString("mqtt.broker"), token.Error())
		os.Exit(1)
	}
}

type Payload struct {
	Token  string `json:"token"`
	Values []byte `json:"values"`
}

//上报属性消息
func Send(valuse []byte, accessToken string) (err error) {
	var payload = Payload{
		Token:  accessToken,
		Values: valuse,
	}
	// payload转json
	payload_json, err := json.Marshal(payload)
	if err != nil {
		log.Println("payload转json失败", err.Error())
		return err
	}
	var qos byte
	if viper.GetInt("mqtt.qos") == 0 {
		qos = 0
	} else {
		qos = 1
	}
	var topic string = viper.GetString("mqtt.topic_to_publish")
	log.Println("topic:", topic)
	t := mqtt_client.Publish(topic, qos, false, payload_json)
	if t.Error() != nil {
		log.Println("发送消息失败...", string(payload_json), t.Error())
	} else {
		log.Println("发送成功：", string(payload_json))
	}
	return t.Error()
}

//发送在线离线消息
func SendStatus(accessToken string, status string) (err error) {
	payload := `{"accessToken":"` + accessToken + `","values":{"status":"` + status + `"}}`
	t := mqtt_client.Publish(viper.GetString("mqtt.status_topic"), 1, false, string(payload))
	if t.Error() != nil {
		log.Println("发送消息失败...", string(payload), t.Error())
	} else {
		log.Println("发送...", string(payload))
	}
	return t.Error()
}
